package cn.smxy.works.service.impl;

import cn.smxy.client.CategoryClient;
import cn.smxy.client.CollegeClient;
import cn.smxy.client.CommentClient;
import cn.smxy.client.UserClient;
import cn.smxy.constant.PlantConstant;
import cn.smxy.constant.UserConstant;
import cn.smxy.dto.FamilyDto;
import cn.smxy.param.*;
import cn.smxy.pojo.*;
import cn.smxy.util.R;
import cn.smxy.vo.PlantVo;
import cn.smxy.works.mapper.PlantMapper;
import cn.smxy.works.mapper.PlantPictureMapper;
import cn.smxy.works.service.PlantService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

@Service
@Slf4j
public class PlantServiceImpl implements PlantService {

    @Autowired
    private PlantMapper plantMapper;
    @Autowired
    private PlantPictureMapper plantPictureMapper;

    @Autowired
    private UserClient userClient;
    @Autowired
    private CollegeClient collegeClient;
    @Autowired
    private CategoryClient categoryClient;
    @Autowired
    private CommentClient commentClient;
    @Autowired
    private RabbitTemplate rabbitTemplate;

    /**
     * 单种群多科属分页展示
     *
     * @param plantPageParam 分页参数
     * @return
     */
    @Override
    public R page(PlantPageParam plantPageParam) {
        // 拆分参数
        int pageSize = plantPageParam.getPageSize();
        int currentPage = plantPageParam.getCurrentPage();
        Long categoryId = plantPageParam.getCategoryId();
        List<Long> familyIds = plantPageParam.getFamilyIds();
        String fuzzyName = plantPageParam.getFuzzyName();
        Long userId = plantPageParam.getUserId();
        // 条件封装
        QueryWrapper<Plant> queryWrapper = new QueryWrapper<>();
        // 如果种群为空则查询全部
        if (categoryId != null) {
            queryWrapper.eq("category_id", categoryId);
            // 如果科属id不为空，则调用category服务查询需要匹配哪些科属
            if (familyIds != null && familyIds.size() > 0) {
                List<Long> list = categoryClient.list(new FamilyIdsParam(familyIds));
                queryWrapper.in("family_id", list);
            }
        }
        if (userId != null && !userId.equals("")) {
            queryWrapper.eq("user_id", userId);
        }
        if (fuzzyName != null && !fuzzyName.equals("")) {
            queryWrapper.like("plant_specific", fuzzyName).or().like("latin_name", fuzzyName);
        }
        // 使用分页插件IPage
        IPage<Plant> page = new Page<>(currentPage, pageSize);
        page = plantMapper.selectPage(page, queryWrapper);
        // 结果封装
        long total = page.getTotal();
        List<Plant> records = page.getRecords();
        List<PlantVo> plantVoList = new ArrayList<>();
        for (Plant plant : records) {
            PlantVo plantVo = new PlantVo(plant);
            User user = userClient.getUserName(plantVo.getUserId());
            plantVo.setUserName(user.getUserName());
            plantVo.setUserPhoto(user.getUserPhoto());
            plantVoList.add(plantVo);
        }
        R ok = R.ok("查询成功", plantVoList, total);
        log.info("PlantServiceImpl.page业务结束，结果为:{}", ok);
        return ok;
    }

    /**
     * 删除用户对应作品
     *
     * @param userId
     * @return
     */
    @Override
    public R removeByUserId(Long userId) {
        QueryWrapper<Plant> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id",userId);
        List<Plant> plantList = plantMapper.selectList(queryWrapper);
        int rows = plantMapper.delete(queryWrapper);

        List<Long> plantIdList = new ArrayList<>();
        for (Plant plant : plantList) {
            plantIdList.add(plant.getPlantId());
        }
        if(plantIdList.size() > 0) {
            // 删除图库中对应植物图片
            QueryWrapper<PlantPicture> pictureWrapper = new QueryWrapper<>();
            pictureWrapper.in("plant_id", plantIdList);
            plantPictureMapper.delete(pictureWrapper);
        }
        // 发送信息通知其他服务删除相应数据
        for (Long id : plantIdList) {
            rabbitTemplate.convertAndSend("topic.ex", "delete.plant", id);
        }

        log.info("PlantServiceImpl.removeByUserId业务结束，结果为:{}",rows);
        return R.ok("删除成功");
    }

    /**
     * 获取各种群作品数量
     *
     * @param list
     * @return
     */
    @Override
    public int[] getCount(List<Category> list) {
        int[] countList = new int[list.size()];
        for (int i = 0; i < list.size(); i++) {
            QueryWrapper<Plant> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("category_id", list.get(i).getCategoryId());
            Integer count = Math.toIntExact(plantMapper.selectCount(queryWrapper));
            countList[i] = count;
        }
        log.info("PlantServiceImpl.getCount业务结束，结果为:{}", countList);
        return countList;
    }

    /**
     * 获取所有植物列表
     *
     * @return
     */
    @Override
    public List<Plant> list() {
        return plantMapper.selectList(null);
    }

    /**
     * 获取植物信息
     * 由校园模块调用
     *
     * @param plantId
     * @return
     */
    @Override
    public PlantVo info(Long plantId) {
        Plant plant = plantMapper.selectById(plantId);
        PlantVo plantVo = new PlantVo(plant);
        User user = userClient.getUserName(plantVo.getUserId());
        plantVo.setUserName(user.getUserName());
        plantVo.setUserPhoto(user.getUserPhoto());
        log.info("PlantServiceImpl.info业务结束，结果为:{}", plantVo);
        return plantVo;
    }

    /**
     * 展示所有植物图片
     *
     * @param search
     * @return
     */
    @Override
    public List<PlantPicture> pictureAll(String search) {
        QueryWrapper<PlantPicture> queryWrapper = new QueryWrapper<>();
        queryWrapper.like("plant_id", search);
        List<PlantPicture> plantPictures = plantPictureMapper.selectList(queryWrapper);
        log.info("PlantServiceImpl.pictureAll业务结束，结果为:{}", plantPictures);
        return plantPictures;
    }

    /**
     * es搜索
     *
     * @param plantSearchParam
     * @return
     */
    @Override
    public R search(PlantSearchParam plantSearchParam) {
        return null;
    }

    /**
     * 查看植物详情
     * 1.查询数据库
     * 2.结果封装并返回
     *
     * @param plantId 植物id
     * @return
     */
    @Override
    public R detail(Long plantId) {
        // 数据库查询
        Plant plant = plantMapper.selectById(plantId);
        PlantVo plantVo = new PlantVo(plant);
        // 拆分参数
        Long userId = plantVo.getUserId();
        Long categoryId = plantVo.getCategoryId();
        Long familyId = plantVo.getFamilyId();
        if (userId == 0) {
            plantVo.setUserName("管理员");
            plantVo.setUserPhoto(UserConstant.ADMIN_PHOTO);
            plantVo.setUserCreateTime(UserConstant.ADMIN_TIME);
        } else {
            User user = userClient.getUserName(userId);
            plantVo.setUserName(user.getUserName());
            plantVo.setUserPhoto(user.getUserPhoto());
            plantVo.setUserCreateTime(user.getCreateTime());
        }
        Category category = categoryClient.getInfo(categoryId);
        plantVo.setCategoryName(category.getCategoryName());
        if (familyId != null && familyId != 0) {
            FamilyDto familyDto = categoryClient.full(familyId);
            plantVo.setFamilyName(familyDto.getFamilyName());
            plantVo.setGenusName(familyDto.getGenusName());
            plantVo.setGenusId(familyDto.getGenusId());
        }
        QueryWrapper<PlantPicture> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("plant_id", plantId);
        List<PlantPicture> plantPictures = plantPictureMapper.selectList(queryWrapper);
        if (plantPictures != null && plantPictures.size() > 0) {
            plantVo.setPlantPictures(plantPictures);
        }
        log.info("PlantServiceImpl.detail业务结束，结果为:{}", plantVo);
        return R.ok(plantVo);
    }

    /**
     * 查看植物图片集(多张图片)
     *
     * @param plantId 植物id
     * @return 植物图片集合
     */
    @Override
    public R picture(Long plantId) {
        QueryWrapper<PlantPicture> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("plant_id", plantId);
        List<PlantPicture> plantPictureList = plantPictureMapper.selectList(queryWrapper);
        R ok = R.ok(plantPictureList);
        log.info("PlantServiceImpl.picture业务结束，结果为:{}", ok);
        return ok;
    }

    /**
     * 植物作品校园认证
     * 1.条件封装
     * 2.调用college服务保存校园植物作品
     *
     * @param plantCampusParam 用户id，植物id，学校id，校园内地址
     * @return
     */
    @Override
    public R campus(PlantCampusParam plantCampusParam) {
        // 封装保存校园植物作品条件
        CollegePlant collegePlant = new CollegePlant();
        collegePlant.setCollegeId(plantCampusParam.getCollegeId());
        collegePlant.setUserId(plantCampusParam.getUserId());
        collegePlant.setPlantId(plantCampusParam.getPlantId());
        collegePlant.setCollegeAddress(plantCampusParam.getCollegeAddress());
        // 调用college服务保存校园植物作品
        R save = collegeClient.save(collegePlant);
        log.info("PlantServiceImpl.campus业务结束，结果为:{}", save);
        return save;
    }

    /**
     * 修改植物作品
     * 1.1 官方认证的作品不能修改
     * 1.2 可以修改植物名，植物别名，拉丁名，种群，科属，描述，地址
     * 2.更新数据
     * 3.发送信息通知es同步数据
     *
     * @param plant 植物实体类
     * @return
     */
    @Override
    public R update(Plant plant) {
        // 查询条件封装
        QueryWrapper<Plant> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("is_choiceness");
        queryWrapper.eq("plant_id", plant.getPlantId());
        // 判断是否发布14天以内的作品和官方认证作品
        Plant one = plantMapper.selectOne(queryWrapper);
        if (one.getIsChoiceness() == 1) {
            log.info("PlantServiceImpl.update业务结束，结果为:{}", "官方认证作品无法修改");
            return R.fail("无法修改");
        }
        int rows = plantMapper.updateById(plant);
        if (rows == 0) {
            log.info("PlantServiceImpl.update业务结束，结果为:{}", "修改植物数据失败");
            return R.fail("修改失败");
        }
        // 发送信息通知es同步数据
        rabbitTemplate.convertAndSend("topic.ex", "insert.plant", plant);

        log.info("PlantServiceImpl.update业务结束，结果为:{}", "修改成功");
        return R.ok("修改成功");
    }

    /**
     * 删除植物作品
     * 1.只能删除发布30天以内的作品，且不能是官方认证作品
     * 2.比对用户id和植物id
     * 3.删除植物
     * 3.1 发送信息通知es同步数据
     * 3.2 通知评论服务删除对应数据
     * 3.3 通知热度服务删除对应数据
     * 3.4 通知收藏服务删除对应数据
     * 3.5 如果是校园认证植物，通知校园服务删除对应数据
     *
     * @param plantRemoveParam
     * @return
     */
    @Transactional
    @Override
    public R remove(PlantRemoveParam plantRemoveParam) {
        // 查询条件封装
        QueryWrapper<Plant> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("create_time", "is_choiceness");
        queryWrapper.eq("plant_id", plantRemoveParam.getPlantId());
        // 判断是否发布14天以内的作品和官方认证作品
        Plant plant = plantMapper.selectOne(queryWrapper);
        long nowTime = System.currentTimeMillis();
        if (plant.getIsChoiceness() == 1
                || nowTime - plant.getCreateTime() > PlantConstant.REMOVE_TIME) {
            log.info("PlantServiceImpl.remove业务结束，结果为:{}", "官方认证或超出删除时间，无法删除");
            return R.fail("无法删除");
        }
        // 删除条件封装
        QueryWrapper<Plant> removeWrapper = new QueryWrapper<>();
        removeWrapper.eq("plant_id", plantRemoveParam.getPlantId());
        removeWrapper.eq("user_id", plantRemoveParam.getUserId());
        // 删除植物
        int rows = plantMapper.delete(removeWrapper);
        if (rows == 0) {
            log.info("PlantServiceImpl.remove业务结束，结果为:{}", "删除失败");
            return R.fail("删除失败");
        }
        // 删除图库中对应植物图片
        QueryWrapper<PlantPicture> pictureWrapper = new QueryWrapper<>();
        pictureWrapper.eq("plant_id", plantRemoveParam.getPlantId());
        plantPictureMapper.delete(pictureWrapper);
        // 发送信息通知其他服务删除相应数据
        rabbitTemplate.convertAndSend("topic.ex", "delete.plant", plantRemoveParam.getPlantId());
        // 删除高校作品
        collegeClient.removePlant(plantRemoveParam.getPlantId());
        // 删除评论
        commentClient.removeByPlantId(plantRemoveParam.getPlantId());

        log.info("PlantServiceImpl.remove业务结束，结果为:{}", "删除成功");
        return R.ok("删除成功");
    }

    /**
     * 上传植物作品
     * 1.设置植物信息初始值
     * 2.保存植物信息
     * 3.保存图片信息
     * 4.发送信息，让es同步数据
     *
     * @param plantAddParam
     * @return
     */
    @Transactional
    @Override
    public R add(PlantAddParam plantAddParam) {
        Plant plant = new Plant();
        // 参数赋值
        BeanUtils.copyProperties(plantAddParam, plant);
        // 初始化参数,创建时间、是否精选
        plant.setCreateTime(System.currentTimeMillis());
        plant.setIsChoiceness(0);
        // 保存植物信息
        int rows = plantMapper.insert(plant);
        if (rows == 0) {
            log.info("PlantServiceImpl.add业务结束，结果为:{}", "添加作品失败");
            return R.fail("添加作品失败");
        }
        // 保存图片信息
        // 对picture对象封装
        String pictures = plantAddParam.getPictures();
        // 将封面图片一起保存到图库中
        if (pictures == null) {
            pictures = plantAddParam.getPlantPicture();
        } else {
            pictures = plantAddParam.getPlantPicture() + "+" + pictures;
        }
        if (!StringUtils.isEmpty(pictures)) {
            // $ + - * | / ? ^符号在正则表达式中有相应的不同意义
            String[] pics = pictures.split("\\+");
            for (String pic : pics) {
                PlantPicture plantPicture = new PlantPicture();
                plantPicture.setPictureIntro(null);
                plantPicture.setPlantId(plant.getPlantId());
                plantPicture.setPlantPicture(pic);
                // 没有可以复用的业务，无法使用mybatis-plus批量插入
                plantPictureMapper.insert(plantPicture);
            }
        }
        // 将封面图片一起保存到图库中
//        PlantPicture plantPicture = new PlantPicture();
//        plantPicture.setPictureIntro(null);
//        plantPicture.setPlantId(plant.getPlantId());
//        plantPicture.setPlantPicture(plant.getPlantPicture());
//        plantPictureMapper.insert(plantPicture);

        // 保存成功，发送信息给es同步数据
        rabbitTemplate.convertAndSend("topic.ex", "insert.plant", plant);

        log.info("PlantServiceImpl.add业务结束，结果为:{}", "添加植物作品成功");
        return R.ok("添加植物作品成功");
    }
}
